package auxiliares;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.StringTokenizer;

import optimizacion.Cromosoma;



public class FuncionesAuxiliares {
	
	
	public static ArrayList<double[][]> leerFicheros(String ruta) throws IOException, NoSuchElementException, NumberFormatException {

		ArrayList<double [][]> matrices = new ArrayList<double [][]>();

		BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream(ruta)));
        StringTokenizer st;       

        st = new StringTokenizer(br.readLine()," ");
        
        int filas = Integer.parseInt(st.nextToken());
         
        br.readLine(); // linea en blanco
         
        double [][] distancias = new double[filas][filas];
	    for (int i = 0; i<filas; i++){
	    	st = new StringTokenizer(br.readLine()," ");
	    	for (int j = 0; j<filas; j++){
	    		distancias[i][j]=Integer.parseInt(st.nextToken());
	    	}
	    	
	    }
	    
	    br.readLine(); // linea en blanco  

	    double [][] flujos= new double[filas][filas];
	    for (int i = 0; i<filas; i++){
	    	st = new StringTokenizer(br.readLine()," ");
	    	for (int j = 0; j<filas; j++){
	    		flujos[i][j]=Integer.parseInt(st.nextToken());
	    	}
	    }
      
	    matrices.add(distancias);
		matrices.add(flujos);	
	    
        br.close();
		   
		return matrices;
	}
	
	/**
	 * Avanza la variable por el array de manera circular, si se encuantra
	 * con una posicion que ya esta rellena avanza otra mas
	 * @param puntosCruce
	 * @param j
	 * @return
	 */
	public static int avanzarJ(int longitud, int[] puntosCruce, int j) {
		j++;
		j %= longitud;
		while (coincidenRandoms(puntosCruce, j)){
			j++;
	    	j %= longitud;
	    		
    	}
    	return j;
	}

	/**
	 * Devuelve true si un random coincide con alguno de los guardados en un array
	 * @param puntosCruce
	 * @param puntoActual
	 * @return
	 */
	public static boolean coincidenRandoms(int[] puntosCruce, int puntoActual) {
		boolean coincide = false;
		int i = 0;
		while (i<puntosCruce.length && !coincide){
			coincide = puntosCruce[i] == puntoActual;
			i++;
		}
		
		return coincide;
	}
	
	public static boolean estanTodasPosicionesArrayRellenas(boolean[] array) {
		boolean completo= true;
		
		int i = 0;
		while (i<array.length && completo){
			completo &= array[i];
			i++;
		}

		return completo;
	}
	
	/**
	 * Devuelve si un array contiene un elemento
	 * @param vector
	 * @param elemento
	 * @return
	 */
	public static boolean contieneElemento (int[] vector, int elemento){
		 
		 boolean encontrado= false;
		 int i=0;
		 while (i< vector.length && !encontrado){	 
			 encontrado = vector[i]== elemento;
		
			 i++; 
		 }
		 return encontrado;
	 }
	
	/**
	 * crea X posiciones random diferentes
	 * @param longitud
	 * @param num
	 * @return
	 */
	public static int[] crearXPosicionesRandomsDistintas(int longitud, int num) {
		int [] puntosCruce = new int [num];
		
		puntosCruce[0] = new Random().nextInt(longitud-1) ;
		int cruce = 0;
		for (int i = 1; i<puntosCruce.length; i++){
			cruce = new Random().nextInt(longitud-1);
			
			while(coincidenRandoms(puntosCruce, cruce)){
				cruce = new Random().nextInt(longitud-1); 
			}
			
			puntosCruce[i] = cruce;
		}
		
		return puntosCruce;
	}
	
	/**
	 * Crea x posicioens randoms diferentes con nextInt(longitud-numARestar)+numASumar
	 * @param longitud
	 * @param numARestar
	 * @param numASumar
	 * @param num
	 * @return
	 */
	public static int[] crearXPosicionesRandomsDistintas(int longitud, int numARestar, int numASumar, int num) {
		int [] puntosCruce = new int [num];
		
		puntosCruce[0] = new Random().nextInt(longitud-numARestar) + numASumar;
		int cruce = 0;
		for (int i = 1; i<puntosCruce.length; i++){
			cruce = new Random().nextInt(longitud-numARestar) + numASumar;
			
			while(coincidenRandoms(puntosCruce, cruce)){
				cruce = new Random().nextInt(longitud-numARestar) + numASumar; 
			}
			
			puntosCruce[i] = cruce;
		}
		
		return puntosCruce;
	}

	public static ArrayList<Integer> convertirArrayToArrayList(int[] array) {
		ArrayList<Integer> al = new ArrayList<Integer>();
		
		for (int i = 0; i<array.length; i++)
			al.add(array[i]);
		
		return al;
	}

	public static int[] convertirArrayListToArray(ArrayList<Integer> al) {
		int [] array = new int[al.size()];
		
		for (int i = 0; i<al.size(); i++)
			array[i] = al.get(i);
		
		return array;
	}
	
	
	/**
	 * Crea una lista ordenada de 1 a tam
	 * @param tam
	 * @return
	 */
	public static ArrayList<Integer> crearListaOrdenadaTamN(int tam) {
		ArrayList<Integer> elementos = new ArrayList<Integer>();
		
		for (int i = 0; i < tam; i++)
			elementos.add(i);
		
		return elementos;
	}
	
	public static int damePosArrayList(ArrayList<Integer> al, int valor) {
		boolean encontrado = false;
		int i = 0;
		int pos = 0;
		
		while ( i < al.size() && !encontrado){
			encontrado = al.get(i) == valor;
			pos = i;
			i++;
		}
		
		return pos;
	}
	
	public static int damePosArray(int [] array, int valor) {
		boolean encontrado = false;
		int i = 0;
		int pos = 0;
		
		while ( i < array.length && !encontrado){
			encontrado = array[i] == valor;
			pos = i;
			i++;
		}
		
		return pos;
	}
	
	
	public static void permutacion(ArrayList<ArrayList<Integer>> res, ArrayList<Integer> act, int k, boolean[] estado, int[] array){
		if (act.size() == k) {
			res.add((ArrayList<Integer>)act.clone());
			return;
		}
		
		for (int i = 0; i < k; i++){
		    if (estado[i]) continue;
		    act.add(array[i]);
		    estado[i] = true;
		    permutacion(res, act, k, estado, array);
		    estado[i] = false;
		    act.remove(new Integer(array[i]));
		}
	}

	public static ArrayList<ArrayList<Integer>> generarPermutaciones(int[] array, int k){
		ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
		ArrayList<Integer> act = new ArrayList<Integer>();
		boolean[] estado = new boolean[k];
		for (int i = 0; i < k; i++){
			estado[i] = false;
		} 
		permutacion(res, act, k, estado, array);
		return res;
	 }
	
	public static int encontrarLista(ArrayList<ArrayList<Integer>> listas,int val){
		
		ArrayList<Integer> list= null;
		int x = 0;
		boolean encontrado=false;
		while (!encontrado){
			list = listas.get(x);
			encontrado=	list.get(0)==val;
			if(!encontrado) x++;
		}
		
		return x;
	
	}
	


	public static Cromosoma crearCromosomaMas1(Cromosoma clone) {
		int longitud = clone.gen.getLongitud();
		int [] genotipo = clone.gen.getGenotipo();
		for (int i = 0; i <longitud; i++)
			genotipo[i] = (genotipo[i] + 1) % longitud;
		
		clone.gen.setGenotipo(genotipo);
		
		return clone;
	}

	public static int decrementarConModulo(int i, int longitud) {
		int dec = i-1;
		if (dec == -1) dec = longitud-1;
		return dec;
	}

	public static int incrementarConModulo(int i, int longitud) {
		return (i+1)  %longitud;
	}
	
	public static void main(String[] args) {
		int[] elementos = new int [] {6,4,3};
		ArrayList<ArrayList<Integer>>  pepe = generarPermutaciones(elementos, elementos.length);
        
	}
}
